#include "comm.hpp"

// 对应程序在加载的时候，会自动构建全局变量！就要调用该类的构造函数 ———— 创建管道
// 程序退出的时候，全局变量会被析构，自动调用析构函数，会自动删除管道文件
Init init;

string TransToHex(key_t k)
{
    char buf[32];
    snprintf(buf, sizeof(buf), "0x%x", k);
    return buf;
}

int main()
{

    // 创建 key
    key_t k = ftok(PHATNAME, PROJ_ID);
    assert(k != -1);
    log("Create key done! ", Debug) << " Server : " << k << endl;

    // 2. 创建共享内存！———— 建议创建一个全新的共享内存 ———— 通信的发起者
    int shmid = shmget(k, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666); // 0666 是设置共享内存的操作权限！默认是没有权限（任何人）
    if (shmid == -1)
    {
        perror("shmget");
        exit(1);
    }
    log("Create shmid done! ", Debug) << " shmid : " << shmid << endl;

    // 3. 将指定的共享内存，挂接到自己的地址空间
    char *shmaddr = (char *)shmat(shmid, nullptr, 0);
    log("Detach shmid done! ", Debug) << " shmid : " << shmid << endl;

    // 该处可设计实现通信
    // 把共享内存当作一个大字符串
#if 0
    for(;;){
        printf("%s\n",shmaddr); // 直接输出：共享内存中的数据
        if(strcmp(shmaddr, "quit") == 0) break;
        sleep(1);
    }
#endif

#if 1
    int fd = OpenFIFO(FIFO_NAME, READ);
    for (;;)
    {
        Wait(fd);

        // 临界区
        printf("%s\n", shmaddr);
        if (strcmp(shmaddr, "quit") == 0)
            break;
        // sleep(1);
    }

#endif
    // 4. 将指定的共享内存，从自己的地址空间中移除！
    int n1 = shmdt(shmaddr);
    assert(n1 != -1);
    (void)n1;
    log("Ndetach shmid done! ", Debug) << " shmid : " << shmid << endl;

    // 删除共享内存！即使有进程和当下shm挂接，依旧直接删除共享内存
    int n2 = shmctl(shmid, IPC_RMID, nullptr);
    assert(n2 != -1);
    (void)n2;
    log("Delete shmid done! ", Debug) << " shmid : " << shmid << endl;

    CloseFifo(fd);
    return 0;
}